package com.uam.core.service;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.Map.Entry;

import com.alibaba.fastjson.support.geo.Polygon;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.elasticsearch.core.convert.GeoConverters.GeoJsonToMapConverter;
import org.springframework.data.elasticsearch.core.geo.GeoJson;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.geo.Feature;
import com.alibaba.fastjson.support.geo.FeatureCollection;
import com.alibaba.fastjson.support.geo.Point;
import com.uam.core.dao.elasticsearch.ElasticsearchDao;
import com.uam.core.entity.enums.ElasticsearchIndices;
import com.uam.core.entity.model.ElasticsearchQueryResult.AreaFields;
import com.uam.core.entity.model.ElasticsearchQueryResult.BaseStationFields;
import com.uam.core.entity.model.ElasticsearchQueryResult.CommonFields;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class DatasService {

	@Value("${charset}")
	private String charset = null;

	@Value("${base.sector.path}")
	private String baseSectorPath = null;

	@Value("${detail.sector.path}")
	private String detailSectorPath = null;

	@Value("${base.station.path}")
	private String baseStationPath = null;

	@Value("${station.path}")
	private String stationPath = null;

	@Value("${io.buffer.size}")
	private int ioBufferSize = 0;

	@Autowired
	private ElasticsearchDao elasticsearchDao = null;

	private String read(String path) throws IOException {
		InputStream in = new FileInputStream(path);
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int n = in.read(buffer);
		while (n != -1) {
			out.write(buffer, 0, n);
			n = in.read(buffer);
		}
		in.close();
		in = null;
		return new String(out.toByteArray(), "UTF-8");
	}

	private FeatureCollection toFeatureCollection(String path) throws IOException {
		return JSON.parseObject(this.read(path), FeatureCollection.class);
	}

	private JSONObject toJSONOBJECT(String path) throws IOException {
		return JSON.parseObject(this.read(path));
	}

	private List<Map<String,Object>> getMap(String path) throws IOException {
		FeatureCollection collection=this.toFeatureCollection(path);
		List<Feature> data= collection.getFeatures();
		List<Map<String, Object>> dataInfo=new ArrayList<>(32);
		for (Feature feature : data){
			Map<String, Object> dataData = new HashMap<String, Object>();
			Map<String,String> properties =feature.getProperties();
			dataData.put(CommonFields.NAME.getName(),properties.get("Name"));
			dataData.put("id",properties.get("Code"));

			Polygon polygons=  (Polygon)  feature.getGeometry();

			dataData.put(AreaFields.BORDER.getName(), GeoJsonToMapConverter.INSTANCE.convert(GeoJson.of(JSON.toJSONString(feature.getGeometry()))));
			dataInfo.add(dataData);
		}
		return dataInfo;
	}
	public static void main(String[] args) throws IOException {
		DatasService datasService=new DatasService();
		List<Map<String,Object>> dataInfo=	datasService.getMap("E:\\ownCode\\UMA\\uam\\uam-core-data\\src\\main\\resources\\data\\districtData.json");

//		System.out.println(dataInfo);
	}
	private Map<String, String> generateId2NameMap(FeatureCollection featureCollection) {
		int i = 0;
		List<Feature> features = featureCollection.getFeatures();
		int size = features.size();
		Map<String, String> id2NameMap = new HashMap<String, String>();
		while (i < size) {
			Map<String, String> properties = features.get(i++).getProperties();
			id2NameMap.put(properties.get("Code"), properties.get("SectorName"));
		}
		return id2NameMap;
	}

	public void importSectorData() {
		try {
			   List<Map<String,Object>> list= getMap("E:\\ownCode\\UMA\\uam\\uam-core-data\\src\\main\\resources\\data\\districtData.json");
				if (this.elasticsearchDao.createIndex(ElasticsearchIndices.SECTOR_INDEX)) {
				list.forEach(a->{
					this.elasticsearchDao.save(ElasticsearchIndices.SECTOR_INDEX, a.get("id")+"", a);
				});
			} else {
				DatasService.log.error("创建扇区索引失败");
			}
		} catch (IOException e) {
			DatasService.log.error("加载数据失败", e);
		}
	}

	public void importStationData() {
		int i = 0;
		try {
			FeatureCollection featureCollection = this.toFeatureCollection(this.stationPath);
			if (this.elasticsearchDao.createIndex(ElasticsearchIndices.STATION_INDEX)) {
				List<Feature> features = featureCollection.getFeatures();
				int size = features.size();
				while (i < size) {
					Feature feature = features.get(i++);
					Map<String, Double> position = new HashMap<String, Double>();
					Point point = (Point) feature.getGeometry();
					position.put(CommonFields.LON.getName(), Double.valueOf(point.getLongitude()));
					position.put(CommonFields.LAT.getName(), Double.valueOf(point.getLatitude()));
					Map<String, Object> data = new HashMap<String, Object>();
					data.put(CommonFields.POSITION.getName(), position);
					Map<String, String> properties = feature.getProperties();
					data.put(CommonFields.ALTITUDE.getName(), Double.valueOf(properties.get("Height")));
					data.put(CommonFields.STATUS.getName(), Integer.valueOf(properties.get("Status")));
					if (this.elasticsearchDao.save(ElasticsearchIndices.STATION_INDEX, data)) {
						DatasService.log.error("{}导入失败", properties.get("Name"));
					}
				}
			} else {
				DatasService.log.error("创建起降点索引失败");
			}
		} catch (IOException e) {
			DatasService.log.error("加载数据失败", e);
		}
	}

	public void importBaseStationData() {
		int i = 0;
		try {
			JSONObject featureCollection = JSON.parseObject(this.read("C:\\Users\\Administrator\\Desktop\\baseNewData.json"));
			if (this.elasticsearchDao.createIndex(ElasticsearchIndices.BASE_STATION_INDEX)) {
				JSONArray features = featureCollection.getJSONArray("features");
				int size = features.size();
				while (i < size) {
					int j = 0;
					JSONObject feature = features.getJSONObject(i++);
					Map<String, Double> position = new HashMap<String, Double>();
					JSONArray coordinates = feature.getJSONObject("geometry").getJSONArray("coordinates");
					position.put(CommonFields.LON.getName(), Double.valueOf(coordinates.getDoubleValue(j++)));
					position.put(CommonFields.LAT.getName(), Double.valueOf(coordinates.getDoubleValue(j)));
					Map<String, Object> data = new HashMap<String, Object>();
					data.put(CommonFields.POSITION.getName(), position);
					JSONObject properties = feature.getJSONObject("properties");
					String id = (String) properties.remove(CommonFields.ID.getName());
					Iterator<Entry<String, Object>> iterator = properties.getJSONObject("extData").entrySet()
							.iterator();
					while (iterator.hasNext()) {
						Entry<String, Object> entry = iterator.next();
						String key = entry.getKey().trim();
						if (!key.startsWith("polarization")) {
							if (CommonFields.NAME.getName().equalsIgnoreCase(key)) {
								data.put(key, (String) entry.getValue());
							} else if (BaseStationFields.FREQUENCY.getName().equalsIgnoreCase(key)) {
								data.put(key, ((Integer) entry.getValue()).toString());
							} else if (BaseStationFields.MINFREQ.getName().equalsIgnoreCase(key)
									|| BaseStationFields.MAXFREQ.getName().equalsIgnoreCase(key)) {
								data.put(key, Double.valueOf(((Integer) entry.getValue()).doubleValue()));
							} else if (CommonFields.STATUS.getName().equalsIgnoreCase(key)) {
								try {
									data.put(key, Integer.valueOf((String) entry.getValue()));
								}catch (Exception e){
									data.put(key,  entry.getValue());
								}
							} else {
								data.put(key, (Integer) entry.getValue());
							}
						}
					}
					if (this.elasticsearchDao.save(ElasticsearchIndices.BASE_STATION_INDEX, id, data)) {
						DatasService.log.error("{}导入失败", properties.get(CommonFields.ID.getName()));
					}
				}
			} else {
				DatasService.log.error("创建基站索引失败");
			}
		} catch (IOException e) {
			DatasService.log.error("加载数据失败", e);
		}
	}

	public void createRouteComponentIndex() {
		if (!this.elasticsearchDao.createIndex(ElasticsearchIndices.ROUTE_COMPONENT_INDEX)) {
			DatasService.log.error("创建路径零件索引失败");
		}
	}

	public void createRouteIntegrationIndex() {
		if (!this.elasticsearchDao.createIndex(ElasticsearchIndices.ROUTE_INTEGRATION_INDEX)) {
			DatasService.log.error("创建路径线索引失败");
		}
	}

	public void createNoFlyAreaIndex() {
		if (!this.elasticsearchDao.createIndex(ElasticsearchIndices.NO_FLY_AREA_INDEX)) {
			DatasService.log.error("创建禁飞区索引失败");
		}
	}

	public void initDatas() {
//		this.importSectorData();
//		this.importStationData();
		this.importBaseStationData();
//		this.createRouteComponentIndex();
//		this.createRouteIntegrationIndex();
//		this.createNoFlyAreaIndex();
	}

}
